import { B3dmData, B3dmHeader } from './types';

/**
 * 解析B3DM二进制数据
 * @param arrayBuffer B3DM文件的ArrayBuffer
 * @returns 解析后的B3DM数据结构
 */
export function parseB3dm(arrayBuffer: ArrayBuffer): B3dmData {
  const dataView = new DataView(arrayBuffer);
  let offset = 0;

  // 1. 解析文件头（28字节）
  const header: B3dmHeader = {} as B3dmHeader;

  header.magic = String.fromCharCode(
    dataView.getUint8(offset++),
    dataView.getUint8(offset++),
    dataView.getUint8(offset++),
    dataView.getUint8(offset++)
  );
  header.version = dataView.getUint32(offset, true); offset += 4;
  header.byteLength = dataView.getUint32(offset, true); offset += 4;
  header.featureTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;
  header.featureTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;
  header.batchTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;
  header.batchTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;

  // 校验文件标识
  if (header.magic !== 'b3dm') {
    throw new Error('Invalid B3DM file: magic number mismatch');
  }

  // 2. 解析特征表
  const featureTableJSON = JSON.parse(
    new TextDecoder().decode(
      new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableJSONByteLength))
    )
  );
  offset += header.featureTableJSONByteLength;

  const featureTableBinary = header.featureTableBinaryByteLength > 0
    ? new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableBinaryByteLength))
    : undefined;
  offset += header.featureTableBinaryByteLength;

  // 3. 解析批量表（可选）
  let batchTable = undefined;
  if (header.batchTableJSONByteLength > 0) {
    const batchTableJSON = JSON.parse(
      new TextDecoder().decode(
        new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableJSONByteLength))
      )
    );
    offset += header.batchTableJSONByteLength;

    const batchTableBinary = header.batchTableBinaryByteLength > 0
      ? new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableBinaryByteLength))
      : undefined;
    offset += header.batchTableBinaryByteLength;

    batchTable = { json: batchTableJSON, binary: batchTableBinary };
  }
   
  
  // 4. 提取GLB数据（剩余部分）
  const glbData = new Uint8Array(arrayBuffer.slice(offset));

  return { header, featureTable: { json: featureTableJSON, binary: featureTableBinary }, batchTable, glbData };
}